 /* Copyright (C)
  * 2024 ZKLX Optoelectronic Technology Co.LTD
  * All rights reserved.
  */
 /**
  * @file web_viewer.cpp
  * @brief jcvp web engine
  * @author xuke
  * @version 1.0
  * @date 2024-10-15
  */

#include <iostream>
#include <fstream>
#include <thread>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <nlohmann/json.hpp>
#include <opencv2/opencv.hpp>
#include <jcvp_web/jcvp.h>
#include "web_viewer.h"
#include "cam_basler_ctrl.h"
#include "cam_hik_ctrl.h"
#include "lx_elog/finsh.h"
#define LOG_TAG web_viewer
#include "lx_elog/stor_elog.h"

using njson = nlohmann::json;

/*--------------------------------extern--------------------------------------------*/

/*--------------------------------globals-------------------------------------------*/
JCVP_T *g_jcvp_obj = NULL;
BaslerCamCtrl *g_basler_cam = NULL;

/*--------------------------------locals--------------------------------------------*/
static CAM_IF_INFO g_cam_if = {"/dev/ttyS17", "hik", 9600};

/*--------------------------------funcs---------------------------------------------*/
// json ctrl reciver
static void jcvp_jc_recive_task(void *args)
{
	std::string jc_str;
	char *cmd_type = NULL;
	uint32_t echo_cnt = 0;
	uint32_t recv_size = 0;
	int32_t last_index = 0;
	std::ofstream *output_file = NULL;
	std::string file_path;

	while (true) {
		if (!g_jcvp_obj->_conn) { //is connected
			sleep(1);
			continue;
		}

		jc_str = g_jcvp_obj->jc_recv();
		njson root_obj = njson::parse(jc_str);
		if (root_obj["type"] == "cam_ctrl") {
			if (g_cam_if.name == "basler") {
				if (root_obj.contains("Width")) {
					g_basler_cam->SetImageWidth(root_obj["Width"]);
				}
				if (root_obj.contains("Height")) {
					g_basler_cam->SetImageHeight(root_obj["Height"]);
				}
			} else if (g_cam_if.name == "hik") {
			} else if (g_cam_if.name == "aik") {
			}
		} else if (root_obj["type"] == "cam_init") {
			if (root_obj.contains("cam_uart")) {
				g_cam_if.uart = root_obj["cam_uart"];
			}
			if (root_obj.contains("cam_name")) {
				g_cam_if.name = root_obj["cam_name"];
			}
			if (root_obj.contains("cam_baudrate")) {
				g_cam_if.baudrate = root_obj["cam_baudrate"];
			}
		} else {
			log_w("unknown msg type!");
		}
	}
}

// json status sender
static void jcvp_js_update_task(void *args)
{
	while (true) {
		if (g_jcvp_obj->_conn) { //is connected
			njson root_obj;

			root_obj["type"] = "cam_state";
			root_obj["cam_name"] = g_cam_if.name;
			if (g_cam_if.name == "basler") {
				root_obj["Width"] = g_basler_cam->GetImageWidth();
				root_obj["Height"] = g_basler_cam->GetImageHeight();
			} else if (g_cam_if.name == "hik") {
			} else if (g_cam_if.name == "aik") {
			}

			g_jcvp_obj->jc_send(root_obj.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace));
		}
		usleep(40*1000);
	}
}

int web_viewer_init(std::string web_root, int port, int fps, float img_scaling)
{
	// init jcvp_web server
	g_jcvp_obj = new JCVP_T(web_root, port, fps, img_scaling); //web_root, fps, img_scaling
	g_jcvp_obj->webs_run();

	// jc task
	std::thread jcvp_jc_thread(jcvp_jc_recive_task, nullptr);
	jcvp_jc_thread.detach();

	// js task
	std::thread jcvp_js_thread(jcvp_js_update_task, nullptr);
	jcvp_js_thread.detach();

	return 0;
}

SPDK_LOG_REGISTER_COMPONENT(web_viewer)
